<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace User\Controller;

use Admin\Controller\AdminActionController;
use Admin\Data\Common;
use Doctrine\ORM\EntityManager;
use Laminas\Mvc\I18n\Translator;
use Laminas\View\Model\JsonModel;
use User\Entity\BalanceLog;
use User\Entity\User;
use User\Entity\UserRecharge;
use User\Entity\UserWithdraw;
use User\Form\EditUserBalanceForm;
use User\Form\ReviewWithdrawForm;
use User\Form\SearchBalanceLogForm;
use User\Form\SearchRechargeForm;
use User\Form\SearchWithdrawForm;
use User\Service\BalanceLogManager;
use User\Service\UserManager;
use User\Service\UserRechargeManager;
use User\Service\UserWithdrawManager;

class BalanceController extends AdminActionController
{
    private $translator;
    private $entityManager;
    private $balanceLogManager;
    private $userManager;
    private $userRechargeManager;
    private $userWithdrawManager;

    public function __construct(
        Translator      $translator,
        EntityManager   $entityManager,
        UserManager     $userManager,
        BalanceLogManager $balanceLogManager,
        UserRechargeManager $userRechargeManager,
        UserWithdrawManager $userWithdrawManager
    )
    {
        $this->translator       = $translator;
        $this->entityManager    = $entityManager;
        $this->userManager      = $userManager;
        $this->balanceLogManager= $balanceLogManager;
        $this->userRechargeManager  = $userRechargeManager;
        $this->userWithdrawManager  = $userWithdrawManager;
    }

    /**
     * 余额记录
     * @return array|\Laminas\View\Model\ViewModel
     */
    public function indexAction()
    {
        $page = (int) $this->params()->fromQuery('page', 1);

        $search = [];
        $searchForm = new SearchBalanceLogForm();
        $searchForm->get('balance_change_type')->setValueOptions(Common::balanceChangeType($this->translator));
        if($this->getRequest()->isGet()) {
            $data = $this->params()->fromQuery();
            $searchForm->setData($data);
            if($searchForm->isValid()) $search = $searchForm->getData();
        }

        $query = $this->entityManager->getRepository(BalanceLog::class)->findUserBalanceLog($search);
        $paginator  = $this->adminCommon()->shopPaginator($query, $page);

        return ['balanceLogList' => $paginator, 'searchForm' => $searchForm];
    }

    /**
     * 客户余额调整
     * @return array|\Laminas\Http\Response
     */
    public function editUserBalanceAction()
    {
        $userId     = (int) $this->params()->fromRoute('id', -1);
        $userInfo   = $this->entityManager->getRepository(User::class)->findOneByUserId($userId);
        if($userInfo == null) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该用户不存在!'));
            return $this->redirect()->toRoute('user');
        }

        $queryData = $this->params()->fromQuery();

        $form = new EditUserBalanceForm($userInfo);
        $form->get('changeBalance')->setValueOptions(Common::changeType($this->translator));

        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if($form->isValid()) {
                $data = $form->getData();

                $this->entityManager->beginTransaction();
                try {
                    $updateBalance = [];
                    if($data['changeBalanceNum'] > 0) {
                        $changeBalanceNum = $data['changeBalance'].$data['changeBalanceNum'];
                        $userMoney  = $userInfo->getUserMoney() + $changeBalanceNum;
                        $message    = $this->translator->translate('管理员调整客户余额') . ' ' . $this->translator->translate('被调整客户:').$userInfo->getUserName() . ',' . $this->translator->translate('调整值:').$changeBalanceNum;
                        $this->balanceLogManager->addBalanceLog([
                            'userId'            => $userId,
                            'userName'          => $userInfo->getUserName(),
                            'balanceChangeType' => 1,//后台处理
                            'balanceChangeNum'  => $changeBalanceNum,
                            'balanceChangedAmount' => $userMoney,
                            'balanceChangeTime' => time(),
                            'balanceChangeInfo' => $data['changeBalanceInfo'],
                            'adminId'           => $this->adminCommon()->admin('admin_id'),
                            'adminName'         => $this->adminCommon()->admin('admin_name')
                        ]);
                        $updateBalance['userMoney'] = $userMoney;
                        $this->adminCommon()->addOperLog($message, $this->translator->translate('余额'), false);
                    }
                    //更新客户余额
                    if(!empty($updateBalance)) {
                        $this->getEventManager()->trigger('backstage-user-balance.change.post', $this, ['user' => $userInfo, 'data' => ['changeTime' => date("Y年m月d日H时i分"), 'changeAmountType' => $data['changeBalance'] == '+'? $this->translator->translate('增加') : $this->translator->translate('减少'), 'changeUserAmount' => $data['changeBalanceNum'], 'userAmount' => $updateBalance['userMoney']]]);

                        $this->userManager->updateUserMoney($updateBalance['userMoney'], $userInfo);
                    }

                    $this->entityManager->commit();

                    $this->flashMessenger()->addSuccessMessage($userInfo->getUserName() . ' ' . $this->translator->translate('余额调整完成'));
                } catch (\Exception $e) {
                    $this->entityManager->rollback();
                    $this->flashMessenger()->addWarningMessage($userInfo->getUserName() . ' ' . $this->translator->translate('余额调整失败'));
                }

                return $this->redirect()->toRoute('user', [], ['query' => $queryData]);
            }
        } else $form->setData(['userName' => $userInfo->getUserName()]);

        return ['userInfo' => $userInfo, 'form' => $form, 'queryData' => $queryData];
    }

    /**
     * 充值列表显示
     * @return array
     */
    public function rechargeListAction()
    {
        $page = (int) $this->params()->fromQuery('page', 1);

        $search = [];
        $searchForm = new SearchRechargeForm();
        $searchForm->get('pay_state')->setValueOptions(Common::payStatus($this->translator));
        if($this->getRequest()->isGet()) {
            $data = $this->params()->fromQuery();
            $searchForm->setData($data);
            if($searchForm->isValid()) $search = $searchForm->getData();
        }

        $query = $this->entityManager->getRepository(UserRecharge::class)->findUserRechargeList($search);
        $paginator = $this->adminCommon()->shopPaginator($query, $page);

        $noPayCount = $this->entityManager->getRepository(UserRecharge::class)->count(['payState' => 10]);

        $rechargeAmount = $this->entityManager->getRepository(UserRecharge::class)->findUserRechargeAmount($search);

        return [
            'noPayCount'    => $noPayCount,
            'rechargeList'  => $paginator,
            'currencySymbol'=> Common::configValue('default', 'currency')['symbol'],
            'rechargeAmount'=> $rechargeAmount,
            'searchForm'    => $searchForm
        ];
    }

    /**
     * 充值删除
     * @return JsonModel
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function deleteRechargeAction()
    {
        $rechargeId     = (int) $this->params()->fromRoute('id', -1);
        $rechargeInfo   = $this->entityManager->getRepository(UserRecharge::class)->findOneBy(['rechargeId' => $rechargeId, 'payState' => 10]);
        if($rechargeInfo == null) return new JsonModel(['msg' => $this->translator->translate('该充值信息不存在')]);

        $this->userRechargeManager->deleteUserRecharge($rechargeInfo);
        $this->adminCommon()->addOperLog($this->translator->translate('充值记录删除成功!'), $this->translator->translate('余额'));

        return new JsonModel(['state' => 'ok']);
    }

    /**
     * 删除全部未支付记录
     * @return mixed
     */
    public function deleteNoPayRechargeAction()
    {
        $this->userRechargeManager->clearNoPayUserRecharge();
        $this->adminCommon()->addOperLog($this->translator->translate('删除全部未充值记录!'), $this->translator->translate('余额'));

        return $this->adminCommon()->toReferer();
    }

    /**
     * 提现申请列表
     * @return array
     */
    public function withdrawListAction()
    {
        $page = (int) $this->params()->fromQuery('page', 1);

        $search = [];
        $searchForm = new SearchWithdrawForm();
        $searchForm->get('withdraw_state')->setValueOptions(Common::withdrawState($this->translator));
        if($this->getRequest()->isGet()) {
            $data = $this->params()->fromQuery();
            $searchForm->setData($data);
            if($searchForm->isValid()) $search = $searchForm->getData();
        }

        $query = $this->entityManager->getRepository(UserWithdraw::class)->findAllWithdrawList($search);
        $paginator = $this->adminCommon()->shopPaginator($query, $page);

        $withdrawAmount = $this->entityManager->getRepository(UserWithdraw::class)->findAllWithdrawAmount($search);

        return [
            'withdrawList'  => $paginator,
            'currencySymbol'=> Common::configValue('default', 'currency')['symbol'],
            'withdrawAmount'=> $withdrawAmount,
            'searchForm'    => $searchForm
        ];
    }

    /**
     * 提现审核处理
     * @return array|\Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function reviewWithdrawAction()
    {
        $withdrawId = (int) $this->params()->fromRoute('id', -1);
        $withdrawInfo = $this->entityManager->getRepository(UserWithdraw::class)->findOneBy(['withdrawId' => $withdrawId]);
        if($withdrawInfo == null || $withdrawInfo->getWithdrawState() != 1) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('该提现申请不存在或提现状态不允许审核!'));
            return $this->redirect()->toRoute('user-balance', ['action' => 'withdrawList']);
        }

        $userInfo = $this->entityManager->getRepository(User::class)->findOneBy(['userId' => $withdrawInfo->getUserId()]);
        if($withdrawInfo->getMoneyChangeNum() > $userInfo->getUserMoney()) {
            $this->flashMessenger()->addWarningMessage($this->translator->translate('申请提现金额大于客户当前余额!'));
            return $this->redirect()->toRoute('user-balance', ['action' => 'reviewWithdraw', 'id' => $withdrawInfo->getWithdrawId()]);
        }

        $form = new ReviewWithdrawForm();
        $form->get('withdrawState')->setValueOptions(Common::withdrawState($this->translator));

        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();

                if($data['withdrawState'] == 2 && $withdrawInfo->getWithdrawFee() > 0 && ($userInfo->getUserMoney() - $withdrawInfo->getMoneyChangeNum() - $withdrawInfo->getWithdrawFee()) < 0) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('余额中没有足够的手续费扣除!'));
                    return $this->adminCommon()->toReferer();
                }

                $data['adminId']    = $this->adminCommon()->admin('admin_id');
                $data['adminName']  = $this->adminCommon()->admin('admin_name');
                $data['withdrawFinishTime'] = time();
                $withdrawInfo = $this->userWithdrawManager->editUserWithdraw($data, $withdrawInfo);

                if($data['withdrawState'] == 2) {
                    $this->entityManager->beginTransaction();
                    try {
                        $userMoney  = $userInfo->getUserMoney() - $withdrawInfo->getMoneyChangeNum();
                        $this->balanceLogManager->addBalanceLog([
                            'userId'            => $withdrawInfo->getUserId(),
                            'userName'          => $withdrawInfo->getUserName(),
                            'balanceChangeType' => 3,//提现处理
                            'balanceChangeNum'  => '-'.$withdrawInfo->getMoneyChangeNum(),
                            'balanceChangedAmount' => $userMoney,
                            'balanceChangeTime' => time(),
                            'balanceChangeInfo' => $data['withdrawInfo'],
                            'adminId'           => $data['adminId'],
                            'adminName'         => $data['adminName']
                        ]);
                        if ($withdrawInfo->getWithdrawFee() > 0) {//手续费
                            $userMoney = $userMoney - $withdrawInfo->getWithdrawFee();
                            $this->balanceLogManager->addBalanceLog([
                                'userId'            => $withdrawInfo->getUserId(),
                                'userName'          => $withdrawInfo->getUserName(),
                                'balanceChangeType' => 8,//提现处理
                                'balanceChangeNum'  => '-'.$withdrawInfo->getWithdrawFee(),
                                'balanceChangedAmount' => $userMoney,
                                'balanceChangeTime' => time(),
                                'balanceChangeInfo' => $data['withdrawInfo'],
                                'adminId'           => $data['adminId'],
                                'adminName'         => $data['adminName']
                            ]);
                        }
                        $this->userManager->updateUserMoney($userMoney, $userInfo);

                        $this->entityManager->commit();
                        $this->adminCommon()->addOperLog($this->translator->translate('提现审核通过，提现人 ').$userInfo->getUserName().'，提现金额'.$withdrawInfo->getMoneyChangeNum(), $this->translator->translate('余额'));
                    } catch (\Exception $e) {
                        $this->entityManager->rollback();
                        $this->flashMessenger()->addWarningMessage($this->translator->translate('提现审核通过失败!'));
                    }
                } elseif ($data['withdrawState'] == 3) $this->adminCommon()->addOperLog($this->translator->translate('提现审核申请驳回'), $this->translator->translate('余额'));

                return $this->redirect()->toRoute('user-balance', ['action' => 'withdrawList']);
            }
        }

        return ['userInfo' => $userInfo, 'withdrawInfo' => $withdrawInfo, 'form' => $form];
    }

    /**
     * 删除提现申请
     * @return JsonModel
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function deleteWithdrawAction()
    {
        $withdrawId = (int) $this->params()->fromRoute('id', -1);
        $withdrawInfo = $this->entityManager->getRepository(UserWithdraw::class)->findOneBy(['withdrawId' => $withdrawId]);
        if($withdrawInfo == null || $withdrawInfo->getWithdrawState() != 1) return new JsonModel(['msg' => $this->translator->translate('该提现申请不存在或提现状态不允许删除!')]);

        $this->userWithdrawManager->deleteUserWithdraw($withdrawInfo);
        $this->adminCommon()->addOperLog($this->translator->translate('提现申请删除成功!'), $this->translator->translate('余额'));

        return new JsonModel(['state' => 'ok']);
    }
}